child_process 是 Node.js 的一个核心模块,可以用于创建子进程,

因此虽然 js 是单线程的,但通过创建子进程也能实现多任务并行处理,也可通过其调用系统的功能指令完成复杂的任务。

主要提供了 4 个方法:spawnexecexecFilefork

下面逐一介绍各个方法的用法和作用。

1 spawn 方法

支持 同步(spawnSync)异步(spawn) 2 种调用方式。

比如我们经常用 pwd 获取当前目录的路径,ls 获取当前目录下的文件,下面是通过 spawnSync 调用示例。

```js import ChildProcess from 'child_process'

const { spawn, spawnSync } = ChildProcess

const pwd = spawnSync('pwd') console.log(pwd.stdout.toString()) const ls = spawnSync('ls', ['-lh']) console.log(ls.stdout.toString()) ```

通过 Git 获取某个文件最近一次的改动时间,

sh git log -1 --pretty="%ci" ../fs/index.mjs

下面是 spawn 实现。

```js import ChildProcess from 'child_process'

const { spawn, spawnSync } = ChildProcess const file = './../fs/index.mjs' const spawnProcess = spawn('git', ['log', '-1', '--pretty="%ci"', file]) spawnProcess.stdout.on('data', (data) => { console.log(stdout: ${data}) console.log(new Date(data)) }) ```

有时候我们就想直接执行,让它按照之前的方式正常打印 log 和交互,不需要内部处理。

可以设置 stdio:'inherit',表示将子进程的标准输入/输出/错误流与父进程共享。

```js spawnSync('pwd', { stdio: 'inherit' })

spawn('ls', { stdio: 'inherit' }) ```

2 exec 方法

同样的也是支持同步和异步两种 execexecSync

简单的实现一下上面的例子。

```js import { exec, execSync } from 'child_process'

const pwd = execSync('pwd') console.log(pwd.toString()) const ls = execSync('ls -lh') console.log(ls.toString())

const file = './../fs/index.mjs' const execProcess = exec(git log -1 --pretty="%ci" ${file}) execProcess.stdout.on('data', (data) => { console.log(stdout: ${data}) console.log(new Date(data)) }) ```

3 execFile 方法

执行某个可执行文件,支持同步和异步两种方式,

我们先编写一个可执行文件 hello,代码内容如下。

```js

!/usr/bin/env node

const hello = 'hello world' console.log(hello) console.log(process.env) ```

通过 execFile 调用执行。

```js import { execFile, execFileSync } from 'child_process'

const file = './hello' const execData = execFileSync(file) console.log(execData.toString())

execFile(file, (error, stdout, stderr) => { if (error) { throw error } console.log(stdout) console.log(stderr) }) ```

4 fork 方法

在父进程中,我们可以使用 fork() 方法创建一个子进程,并与子进程进行通信,

下面是具体的例子。

child.mjs 代码如下。

js process.on('message', (msg) => { // 监听来自父进程的消息 console.log(`Message from parent: ${msg}`) process.send('Hello from child!') // 向父进程发送消息 })

fork.mjs 代码如下。

```js import { fork } from 'child_process'

const child = fork('child.mjs') // 使用 fork() 方法创建子进程

child.on('message', (msg) => { // 监听来自子进程的消息 console.log(Message from child: ${msg}) })

child.send('Hello from parent!') // 向子进程发送消息 ```

运行结果如下。

小结

通过 child_process 可以创建子进程实现多任务并行处理,也可通过其调用系统的功能指令完成复杂的任务,

主要介绍了如下 4 个方法的用法和作用。